package org.example.payment.service.impl;

import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.RSAPublicKeyNotificationConfig;
import com.wechat.pay.java.service.partnerpayments.app.model.Transaction;
import com.wechat.pay.java.service.payments.h5.H5Service;
import com.wechat.pay.java.service.payments.h5.model.*;
import lombok.extern.slf4j.Slf4j;
import org.example.common.Response;
import org.example.order.entity.OrderDO;
import org.example.order.service.IOrderService;
import org.example.payment.entity.vo.WechatPayVO;
import org.example.payment.service.IWechatPayService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
@Slf4j
public class WechatPayServiceImpl implements IWechatPayService {

    @Value("${wechat.pay.merchantId}")
    private String merchantId;

    @Value("${wechat.pay.appId}")
    private String appId;

    @Value("${wechat.pay.wechatPublicKeyPath}")
    private String wechatPublicKeyPath;

    @Value("${wechat.pay.wechatPublicKeyId}")
    private String wechatPublicKeyId;

    @Value("${wechat.pay.apiV3Key}")
    private String apiV3Key;

    @Value("${wechat.pay.merchantSerialNumber}")
    private String merchantSerialNumber;

    @Value("${wechat.pay.privateKeyPath}")
    private String privateKeyPath;

    @Resource
    private H5Service h5Service;

    @Resource
    private IOrderService orderService;


    @Override
    public String h5Pay(WechatPayVO wechatPayVO) {
        PrepayRequest request = new PrepayRequest();
        request.setAppid(appId);
        request.setMchid(merchantId);
        request.setDescription("算命报告的付款");
        request.setOutTradeNo(wechatPayVO.getOrderNum());
        request.setNotifyUrl(wechatPayVO.getNotifyUrl());
        Amount amount = new Amount();
        amount.setTotal(wechatPayVO.getTotal()); // 金额：分
        amount.setCurrency("CNY");
        request.setAmount(amount);
        SceneInfo sceneInfo = new SceneInfo();
        sceneInfo.setPayerClientIp(wechatPayVO.getClientIp());
        H5Info h5Info = new H5Info();
        h5Info.setType("Wap"); // 网页浏览器发起的支付
        sceneInfo.setH5Info(h5Info);
        request.setSceneInfo(sceneInfo);
        PrepayResponse response = h5Service.prepay(request);
        return response.getH5Url();
    }

    @Override
    public Response<String> handleNotify(String requestBody, String serial_number, String nonce, String signature, String timestamp) {
        log.info("回调开始" + requestBody + serial_number + nonce + signature + timestamp);
        // 构造请求参数
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(serial_number)
                .nonce(nonce)
                .signature(signature)
                .timestamp(timestamp)
                .body(requestBody)
                .build();

        // 初始化通知配置（根据证书/公钥类型选择不同配置）
        // 2. 如果你仍在使用微信支付平台证书，则使用 RSAAutoCertificateConfig
        NotificationConfig config = new RSAAutoCertificateConfig.Builder()
                .merchantId(merchantId)
                .privateKeyFromPath(privateKeyPath)
                .merchantSerialNumber(merchantSerialNumber)
                .apiV3Key(apiV3Key)
                .build();

        NotificationParser parser = new NotificationParser(config);

        try {
            // 验签并解析通知（以支付通知为例）
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            // 打印接收到的支付信息
            log.info("接收到支付回调：out_trade_no={}, transaction_id={}, trade_state={}",
                    transaction.getOutTradeNo(), transaction.getTransactionId(), transaction.getTradeState());
            // 处理业务逻辑（验证订单状态、更新数据等）
            if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) {
                // 更新订单状态为已支付
                String orderNum = transaction.getOutTradeNo();
                OrderDO orderDO = new OrderDO();
                orderDO.setId(Long.parseLong(orderNum));
                orderDO.setPayType(1);
                orderDO.setWechatOrderNum(transaction.getTransactionId());
                orderService.updateById(orderDO);
            }

            // 返回200状态码确认接收
            return Response.success("success");

        } catch (ValidationException e) {
            // 签名验证失败，返回401
            log.error("签名验证失败");
            Response<String> fail = Response.data("fail");
            fail.setCode(401);
            return fail;
        } catch (Exception e) {
            // 处理异常返回500
            e.printStackTrace();
            Response<String> fail = Response.data("fail");
            fail.setCode(500);
            return fail;
        }
    }
}
